﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net.Sockets;
using System.IO;
using System.Net;
using System.Threading;
using System.Windows.Threading;

namespace TcpIpClientTest
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        int connectionPort = 5555;
        String serverString = "localhost";
        bool connectionEstablished = false;
        ManualResetEvent manualResetEvent = new ManualResetEvent(false);
        Object objeLock = new Object();
        TcpClient clientGlobal = null;
        public Window1()
        {
            InitializeComponent();
        }
        int counter = 0;
        
        private void Service()
        {
            try
            {
                if (clientGlobal == null)
                {
                    clientGlobal = getClientCon();
                    if (clientGlobal == null)
                    {
                        processDelegateInvoke(new Action(delegate()
                        {
                            label2.Content = "Unable To Connect";
                        }));
                        return;
                    }
                }
                Stream s = null;
                try
                {
                    connectionEstablished = true;
                    s = clientGlobal.GetStream();
                    //StreamReader sr = new StreamReader(s);
                    StreamWriter sw = new StreamWriter(s);
                    sw.AutoFlush = true;
                    String tempText = "";
                    while (true)
                    {
                        manualResetEvent.WaitOne();
                        processDelegateInvoke(new Action(delegate()
                        {
                            tempText = textBox1.Text;
                        }));
                        sw.WriteLine(tempText);
                        
                        processDelegateInvoke(new Action(delegate()
                        {
                            label2.Content = "Success :" + counter;
                            counter++;
                        }));
                        manualResetEvent.Reset();
                    }
                    //s.Close();
                }


                catch (Exception)
                {
                    processDelegateInvoke(new Action(delegate()
                    {
                        label2.Content = "Error Sending";
                    }));
                }
                finally
                {
                    if (s != null)
                    {
                        s.Close();
                    }
                    // code in finally block is guranteed 
                    // to execute irrespective of 
                    // whether any exception occurs or does 
                    // not occur in the try block
                    lock (objeLock)
                    {
                        clientGlobal.Close();
                        clientGlobal = null;
                    }
                    connectionEstablished = false;
                }
            }
            catch (Exception) {}
        }
        Thread th = null;
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            if (!connectionEstablished)
            {
                th= new Thread(new ThreadStart(Service));
                th.IsBackground = true;
                th.Start();
                manualResetEvent.Set();    
            }
            else {
                manualResetEvent.Set(); 
            }
        }
    
        private TcpClient getClientCon()
        {
            lock (objeLock)
            {
                TcpClient client = null;
                try
                {
                    //client = new TcpClient("localhost", 2055);

                    processDelegateInvoke(new Action(delegate()
                    {
                        serverString = textBox2.Text.ToString();
                        connectionPort = Convert.ToInt32(textBox3.Text.ToString());
                    }));

                    client = new TcpClient(serverString, connectionPort);
                    return client;
                }
                catch (Exception)
                {
                    return null;
                }
            }
        }
        
        private void processDelegateBeginInvoke(Action act)
        {

            this.Dispatcher.BeginInvoke(DispatcherPriority.DataBind, act);
        }

        private void processDelegateInvoke(Action act)
        {
            this.Dispatcher.Invoke(DispatcherPriority.DataBind, act);
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            if (th != null)
            {
                th.Interrupt();
                connectionEstablished = false;
            }
        }    
    }
}
